import { writeFileSync } from 'fs';
import { resolve } from 'path';

/**
 * 预加载脚本生成器
 */
export class PreloadGenerator {
  /**
   * 生成预加载脚本
   * @param methods IPC 方法列表，格式为 `namespace:method`
   * @param outputPath 输出路径
   */
  public static generate(methods: string[], outputPath: string): void {
    // 按命名空间组织方法
    const namespaces: Record<string, string[]> = {};
    
    for (const method of methods) {
      const [namespace, methodName] = method.split(':');
      
      if (!namespaces[namespace]) {
        namespaces[namespace] = [];
      }
      
      namespaces[namespace].push(methodName);
    }
    
    // 生成预加载脚本内容
    let content = `/**
 * 由 Boltron 自动生成的预加载脚本
 * 生成时间: ${new Date().toISOString()}
 * 请勿手动修改此文件
 */

const { contextBridge, ipcRenderer } = require('electron');

// 安全地暴露 IPC 通信 API 到渲染进程
const electronAPI = {};\n`;
    
    // 添加每个命名空间及其方法
    for (const [namespace, methodList] of Object.entries(namespaces)) {
      content += `\n// ${namespace} 命名空间\nelectronAPI.${namespace} = {};\n`;
      
      for (const methodName of methodList) {
        content += `electronAPI.${namespace}.${methodName} = (...args) => ipcRenderer.invoke('${namespace}:${methodName}', ...args);\n`;
      }
    }
    
    content += `\n// 暴露 API 到全局 window 对象
contextBridge.exposeInMainWorld('electron', electronAPI);

// 创建渲染进程 API 注册辅助函数
contextBridge.exposeInMainWorld('boltron', {
  // 注册渲染进程 API，供主进程调用
  exposeRendererApi: (api) => {
    // 遍历 API 对象并注册每个方法
    Object.entries(api).forEach(([namespace, methods]) => {
      Object.entries(methods).forEach(([methodName, method]) => {
        const channelName = \`renderer:\${namespace}:\${methodName}\`;
        ipcRenderer.on(channelName, (event, ...args) => {
          method(...args);
        });
      });
    });
  }
});
`;
    
    // 写入文件
    writeFileSync(resolve(outputPath), content, 'utf-8');
    console.log(`预加载脚本已生成: ${outputPath}`);
    
    // 同时生成类型定义文件
    this.generateTypeDefinitions(namespaces, outputPath);
  }
  
  /**
   * 生成类型定义文件
   * @param namespaces 命名空间方法映射
   * @param outputPath 预加载脚本输出路径
   */
  private static generateTypeDefinitions(namespaces: Record<string, string[]>, outputPath: string): void {
    const typesOutputPath = outputPath.replace(/\.js$/, '.d.ts');
    
    let content = `/**
 * 由 Boltron 自动生成的类型定义
 * 生成时间: ${new Date().toISOString()}
 * 请勿手动修改此文件
 */

/**
 * Boltron 渲染进程 API 类型
 */
export interface BoltronRendererApi {
  [namespace: string]: {
    [methodName: string]: (...args: any[]) => any;
  };
}

/**
 * Boltron 全局 API
 */
export interface BoltronApi {
  /**
   * 暴露渲染进程 API，使其可以从主进程调用
   * @param api 要暴露的 API 对象
   */
  exposeRendererApi: (api: BoltronRendererApi) => void;
}

/**
 * Electron API 类型
 */
export interface ElectronApi {
`;
    
    // 为每个命名空间生成接口
    for (const [namespace, methodList] of Object.entries(namespaces)) {
      content += `  /**\n   * ${namespace} 命名空间\n   */\n  ${namespace}: {\n`;
      
      for (const methodName of methodList) {
        content += `    /**\n     * ${methodName} 方法\n     */\n    ${methodName}: (...args: any[]) => Promise<any>;\n`;
      }
      
      content += `  };\n\n`;
    }
    
    content += `}

declare global {
  interface Window {
    /**
     * Boltron API
     */
    boltron: BoltronApi;
    
    /**
     * Electron API
     */
    electron: ElectronApi;
  }
}

export {};
`;
    
    // 写入文件
    writeFileSync(resolve(typesOutputPath), content, 'utf-8');
    console.log(`类型定义文件已生成: ${typesOutputPath}`);
  }
} 